import 'package:flutter/material.dart';

/// easy version
// showOrDismiss = true => show
typedef ShowOrDismissCallback(bool showOrDismiss, int overlayId);

final OverlayManager overlayManager = OverlayManager();

class OverlayManager {
  OverlayManager._internal();

  static final OverlayManager _singleton = OverlayManager._internal();

  factory OverlayManager() => _singleton;

  int _overlayId = 0;

  int get overlayId => _overlayId;

  bool _isShow = false;

  bool get isShow => _isShow;

  OverlayEntry _overlayEntry;

  List<ShowOrDismissCallback> _callbacks = [];

  void addListenShowOrDismiss(ShowOrDismissCallback callback) {
    if (null == callback) return;
    _callbacks.add(callback);
  }

  void removeListenShowOrDismiss(ShowOrDismissCallback callback) {
    if (null == callback) return;
    if (_callbacks.contains(callback)) {
      _callbacks.remove(callback);
    }
  }

  int show(Widget child, BuildContext ctx) {
    if (null == child || null == ctx || _isShow) return -1;
    _overlayEntry = OverlayEntry(
      builder: (context) {
        return child;
      },
    );
    final overlayState = Overlay.of(ctx);
    if (null != overlayState) {
      overlayState.insert(_overlayEntry);
      _isShow = true;
      _notifyShowOrDismiss(true);
      return ++_overlayId;
    }
    return -1;
  }

  void dismiss() {
    if (_isShow) {
      if (true == _overlayEntry?.mounted) {
        _overlayEntry.remove();
        _isShow = false;
        _notifyShowOrDismiss(false);
      }
    }
  }

  void _notifyShowOrDismiss(bool showOrDismiss) {
    _callbacks.forEach((element) {
      element?.call(showOrDismiss, _overlayId);
    });
  }
}
